package com.example.jsd2205.vx.emos.config.shiro;

import com.example.jsd2205.vx.emos.db.pojo.TbUser;
import com.example.jsd2205.vx.emos.service.UserService;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Set;


/**
 * OAuth2Realm , AuthorizingRealm的实现类,实现认证与授权
 * @author
 */
@Component
public class OAuth2Realm extends AuthorizingRealm {
    /**
     * 处理token引入工具类
     */
    @Autowired
    private JwtUtil jwtUtil;

    /**
     * 引用
     */
    @Autowired
    private UserService userService;

    /**
     * 判断传入的令牌字符串是否符合要求
     * 是否是OAuth2Token对象的类型
     * @param token
     * @return boolean
     */
    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof OAuth2Token;
    }

    /**
     * 授权(验证权限时调用)
     * @param collection
     * @return AuthorizationInfo授权对象
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection collection) {
        //从参数里获取用户的基本信息
        TbUser user= (TbUser) collection.getPrimaryPrincipal();
        //提取用户主键值
        int userId=user.getId();
        //保存用户权限列表
        Set<String> permsSet=userService.searchUserPermissions(userId);
        //构建授权对象
        SimpleAuthorizationInfo info=new SimpleAuthorizationInfo();
        info.setStringPermissions(permsSet);
        //返回授权对象
        return info;
    }

    /**
     * 认证(验证登录时候调用)
     * @param token
     * @return  AuthenticationInfo认证对象
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        //获取token字符串赋值给变量
        String accessToken = (String) token.getPrincipal();
        //从令牌获取userId
        int userId = jwtUtil.getUserId(accessToken);
        //通过userId获取用户信息
        TbUser user = userService.searchById(userId);
        //判断是否为在职
        if (user==null){
            throw new LockedAccountException("账号已经锁定，请联系管理员");
        }
        SimpleAuthenticationInfo info =new SimpleAuthenticationInfo(user,accessToken,getName());
        return info;
    }

}
